﻿using System.Linq;
using Amazon;
using Amazon.EC2;
using Amazon.EC2.Model;
using Amazon.ElasticLoadBalancing.Model;
using System;
using System.Collections.Generic;

namespace Web_App___AWS_ELB_Monitor
{
    public static class EC2DataHelper
    {
        private const string EC2_EU_ServiceUrl = "https://ec2.eu-west-1.amazonaws.com";

        public static AmazonEC2 EC2Client
        {
            get
            {
                return AWSClientFactory.CreateAmazonEC2Client(CustomValueHelper.GetProperty("AWSAccessKey"),
                                                              CustomValueHelper.GetProperty("AWSSecretKey"),
                                                              new AmazonEC2Config().WithServiceURL(EC2_EU_ServiceUrl));
            }
        }

        public static DescribeInstancesExtendedResult GetInstancesForLoadBalancer(LoadBalancerDescription lb)
        {
            var allInstanceIds = lb.Instances.Select(ins => ins.InstanceId).ToArray();
            return GetInstances(allInstanceIds);
        }

        public static DescribeInstancesExtendedResult GetInstances(params string[] instanceIds)
        {
            /*return EC2Client.DescribeInstances(
                    new DescribeInstancesRequest().WithInstanceId(instanceIds)
                    ).DescribeInstancesResult;*/
            ISet<string> badInstanceIds;
            DescribeInstancesResult result;

            try
            {
                badInstanceIds = new HashSet<string>();
                result = EC2Client.DescribeInstances(
                    new DescribeInstancesRequest().WithInstanceId(instanceIds)
                    ).DescribeInstancesResult;
            }
            catch (AmazonEC2Exception ex)
            {
                var idsString = ex.Message.Replace("The instance IDs '", "").Replace("The instance ID '", "").Replace("' do not exist", "").Replace("' does not exist", "");
                var badIds = idsString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim());
                var badIdLookup = new HashSet<string>(badIds);

                var filteredInstanceIds = instanceIds.Where(id => !badIdLookup.Contains(id)).ToArray();

                badInstanceIds = badIdLookup;
                result = EC2Client.DescribeInstances(
                    new DescribeInstancesRequest().WithInstanceId(filteredInstanceIds)
                    ).DescribeInstancesResult;
            }


            return new DescribeInstancesExtendedResult(result, badInstanceIds);
        }

        public static string GetInstanceFriendlyName(RunningInstance ins)
        {
            Tag nameTag = ins.Tag.FirstOrDefault(tag => tag.Key.ToLower() == "name");
            if (nameTag != null)
                return nameTag.Value;
            else
            {
                return null;
            }
        }
    }

    public class DescribeInstancesExtendedResult {
        public DescribeInstancesResult InstanceDescriptions { get; private set; }
        public ISet<string> BadInstanceIds { get; private set; }

        public DescribeInstancesExtendedResult(DescribeInstancesResult result, ISet<string> badInstanceIds)
        {
            InstanceDescriptions = result;
            BadInstanceIds = badInstanceIds;
        }
    }
}